﻿using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;

namespace Xms.Abp.Core;

public class SerialNumberGenerator : ISerialNumberGenerator, ITransientDependency
{
    protected ISerialNumberProvider SerialNumberProvider { get; }
    public SerialNumberGenerator(
        IOptions<SerialNumberOptions> optionsAccessor,
        IEnumerable<ISerialNumberProvider> serialNumberProviders)
    {
        SerialNumberProvider = serialNumberProviders.FirstOrDefault(r => r.Name == (optionsAccessor.Value.ProviderName ?? "Default"));
    }

    public async Task<long> CreateAsync(string key, int quantity = 1, string tenantId = null, SerialNumberGrowthType growthType = SerialNumberGrowthType.None, CancellationToken cancellationToken = default)
    {
        return await SerialNumberProvider.CreateAsync(key, quantity, growthType, cancellationToken);
    }
}

public class SerialNumberGenerator<T> : ISerialNumberGenerator<T>
    where T : class
{
    protected ISerialNumberProvider SerialNumberProvider { get; }
    protected string SerialNumberKey { get; }
    protected SerialNumberGrowthType GrowthType { get; }
    public SerialNumberGenerator(
        IOptions<SerialNumberOptions> optionsAccessor,
        IOptions<SerialNumberOptions<T>> optionsTAccessor,
        IEnumerable<ISerialNumberProvider> serialNumberProviders)
    {
        SerialNumberProvider = serialNumberProviders.FirstOrDefault(r => r.Name == (optionsTAccessor.Value.ProviderName ?? optionsAccessor.Value.ProviderName ?? "Default"));
        SerialNumberKey = optionsTAccessor.Value.SerialNumberKey ?? typeof(T).FullName;
        GrowthType = optionsTAccessor.Value.GrowthType;
    }

    public async Task<long> CreateAsync(int quantity = 1, string tenantId = null, CancellationToken cancellationToken = default)
    {
        return await SerialNumberProvider.CreateAsync(SerialNumberKey, quantity, GrowthType, cancellationToken);
    }
}
